#-----------------------------------------------------------------------		
#class for town generation
#-----------------------------------------------------------------------

import libtcodpy as libtcod
import map_block


DEBUG_TIME = 0.01

import random, sys, time
		
class MapGenerator:
	def __init__(self, block):
		self.ref_size = block.size()
		self.con = None
		
		self.MIN_BLOCK_SIZE = 1800
		self.MERGE_BLOCKS = True
		
		self.generator = None
		self.chunk_seed  = 123456

	def set_seed(self, seed):
		self.chunk_seed  = seed
		self.generator = libtcod.random_new_from_seed(self.chunk_seed)
		
	def min_block_size(self):
		return self.MIN_BLOCK_SIZE
		
	def MergeBlocks(self, tl, tr, br, bl):
		merged_blocks = []
		blocks = [tl,tr,br,bl]
		
		if not self.MERGE_BLOCKS:
			return blocks
		
		blocks[0].nb = [tr,bl]
		blocks[1].nb = [tl,br]
		blocks[2].nb = [tr,bl]
		blocks[3].nb = [tl,br]

		for block in blocks:
			if (block.size() < self.min_block_size()):

				i = int(libtcod.random_get_int(self.generator,0,3))
				if i < len(blocks) and (blocks[i] in block.nb):

					block.merge(blocks[i])
					del blocks[i]

				
		for block in blocks:
			block.con = self.con
			block.draw


		for block in blocks:
			if block:
				merged_blocks.append(block)

		return merged_blocks
		
	#-------------------------------------------------------------------	
	
	def Process(self, blocks):
		
		if not self.generator:
			self.generator = libtcod.random_new_from_seed(self.chunk_seed)
				
		if len(blocks) == 1 and blocks[0].size() < self.min_block_size():
			return blocks[0]
			
		blocks_divided = []

		for i in range(len(blocks)):
			sub_block = blocks[i]
			
			if (min(sub_block.w,sub_block.h)*3) < max(sub_block.w,sub_block.h):
				splited = self.HalfSplit(sub_block)
			else:
				splited = self.QuadSplit(sub_block)

			if splited:
				for sb in splited:
					blocks_divided.append(sb)
			else:
				blocks_divided.append(sub_block)
				
		if len(blocks_divided) <= len(blocks):	# or ==?
			return blocks
	
		blocks_divided = self.Process(blocks_divided)
				
		return blocks_divided
		
	#-------------------------------------------------------------------
	
	
	def RoomProcess(self,blocks):
		
		if not self.generator:
			self.generator = libtcod.random_new_from_seed(self.chunk_seed)
		
		
		#some tricky algorythms there
		rooms = []
		#TODO: make me a neat room
		for i in range(len(blocks)):
			sub_block = blocks[i]
			
			if (min(sub_block.w,sub_block.h)*2) < max(sub_block.w,sub_block.h):
				splited = self.HalfSplit(sub_block)
			else:
				splited = self.QuadSplit(sub_block)
				
			if splited:
				for sb in splited:
					rooms.append(sb)
					
		#---------------------------------------------------------------
		if len(rooms) <= len(blocks):	# or ==?
			return blocks
	
		rooms = self.RoomProcess(rooms)
		#---------------------------------------------------------------
					
		#TODO: make a doors there
		return rooms
		
	
	def HalfSplit(self,block):
		if block.size() < self.min_block_size():
			return None
			
		blocks = []
		x = block.x
		y = block.y
			
		if block.h > block.w:
			top_offset = int(block.h * libtcod.random_get_int(self.generator,40,60) / 100) 

			top = 	 map_block.Block(x,y,block.w,top_offset)
			bottom = map_block.Block(x,y+top_offset, block.w, block.h-top_offset)
			
			blocks.append(top)
			blocks.append(bottom)
			
		else:
			left_offset = int(block.w * libtcod.random_get_int(self.generator,40,60) / 100)  
			y = block.y
			
			left = 	 map_block.Block(x,y,left_offset,block.h)
			right =  map_block.Block(x+left_offset,y, block.w-left_offset, block.h)
			
			blocks.append(left)
			blocks.append(right)
		
		return blocks
	
	def QuadSplit(self, block):
		
		if block.size() < self.min_block_size():
			return None
		
		left_offset = int(block.w * libtcod.random_get_int(self.generator,40,60) / 100)	#cut 40~60 of base width
		top_offset = int(block.h * libtcod.random_get_int(self.generator,40,60) / 100) 
		
		x = block.x
		y = block.y
		
		w = block.w
		h = block.h
		
		blocks = []
		
		tl = map_block.Block(x,y,left_offset,top_offset)
		tr = map_block.Block(x+left_offset, y, w-left_offset, top_offset)
		br = map_block.Block(x+left_offset,y+top_offset,(w-left_offset),(h-top_offset))
		bl = map_block.Block(x,y+top_offset,left_offset,(h-top_offset))

		blocks = self.MergeBlocks(tl,tr,br,bl)
		
	
		if len(blocks) == 1:
			blocks[0].draw("*")
			
			return None
		
		return blocks
